package com.stylefeng.guns.modular.vpn_connection_manage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.core.base.tips.ErrorTip;
import com.stylefeng.guns.core.base.tips.SuccessTip;
import com.stylefeng.guns.core.common.constant.DatasourceEnum;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.modular.system.dao.VpnAllowIpMapper;
import com.stylefeng.guns.modular.system.model.Connection;
import com.stylefeng.guns.modular.system.dao.ConnectionMapper;
import com.stylefeng.guns.modular.vpn.utils.LogUtil;
import com.stylefeng.guns.modular.vpn.vo.ConnectionBO;
import com.stylefeng.guns.modular.vpn.vo.Paging;
import com.stylefeng.guns.modular.vpn_connection_manage.service.IConnectionService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.vpn_server_info.entity.AllowIp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author stylefeng
 * @since 2020-03-26
 */
@Service
@Slf4j
public class ConnectionServiceImpl extends ServiceImpl<ConnectionMapper, Connection> implements IConnectionService {
    @Autowired
    private ConnectionMapper connectionMapper;

    @Autowired
    private VpnAllowIpMapper allowIpMapper;

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public Paging findConnections(String userName,Integer page, Integer count,Integer serverType) {
        int start = 0;
        if(page > 0){
            start = page - 1;
        }
        Paging<ConnectionBO> paging = new Paging<>();

        Long total = connectionMapper.queryConnectCount(userName,serverType);

        List<ConnectionBO> items =
                connectionMapper.findConnections(userName,start * count,count,serverType);

        paging.setItems(items);
        paging.setTotal(total);
        return paging;
    }

    /**
     * 强制下线
     * @param id
     */
    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    @Transactional
    public Object offLine(Integer id) {
        try {
            ConnectionBO connection = connectionMapper.queryOneConnect(id);
            if(connection  != null && connection.getStatus() == 1){
                Integer allowId = connection.getAllowId();
                //服务器断连
                String jsonStr = configVpnToServer(connection.getServerIP(),connection.getPubKey(),
                        connection.getAllowIP(),connection.getUserName(),"remove");

                JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                if (jsonObject.getInteger("code") != 0){
                    return new ErrorTip(500,jsonObject.getString("msg"));
                }
                //数据库修改连接状态
                Connection con = new Connection();
                con.setConnectId(Math.toIntExact(connection.getId()));
                //1、修改状态
                con.setStatus(0);
                //2、增加断连时间
                con.setUpdateTime(new Date());
                super.baseMapper.updateById(con);
                AllowIp allowIp = allowIpMapper.selectById(allowId);
                if(allowIp != null){
                    //3、修改allow ip 状态
                    allowIp.setStatus(1);
                    allowIpMapper.updateById(allowIp);
                }

                LogUtil.saveOperationLog("断掉用户在线连接",
                        "断掉了用户"+connection.getUserName()+"的在线连接，连接ServerIP："
                        +connection.getServerIP()+"，AllowIP："+connection.getAllowIP());
            }

        } catch (Exception e) {
            log.error("服务器断连失败：{}",e.getMessage());
            e.printStackTrace();
            throw new GunsException(BizExceptionEnum.VPN_OFFLINE_VPN_ERROR);
        }

        return new SuccessTip();
    }

    public String configVpnToServer(String serverIp,
                                  String publicKey,
                                  String allowIp,
                                  String username,
                                  String action) throws Exception{
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://" + serverIp + ":55699";
        MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
        header.add(HttpHeaders.CONTENT_TYPE, (MediaType.APPLICATION_FORM_URLENCODED_VALUE));
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("cli_pub", publicKey);
        map.add("allowed_ip", allowIp);
        map.add("action", action);
        map.add("id", username);
        HttpEntity<String> request = new HttpEntity(map, header);
        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
        log.info("断开连接返回去数据内容：{}",result.getBody());
        return result.getBody();
    }

}
